<?php

/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/9/11
 * Time: 21:17
 */
namespace app\api\service;
use app\api\model\User as UserModel;
use app\lib\enum\ScopeEnum;
use app\lib\exception\TokenException;
use app\lib\exception\WeChatException;
use think\Cache;
use think\Exception;

class UserToken extends Token
{
    protected $code;
    protected $wxAppID;
    protected $wxAppSecret;
    protected $wxLoginUrl;

    function __construct($code)
    {
        $this->code = $code;
        $this->wxAppID = config('wx.app_id');
        $this->wxAppSecret = config('wx.app_secret');
        $this->wxLoginUrl = sprintf(config('wx.login_url'),$this->wxAppID,$this->wxAppSecret,$this->code);
    }

    public function get(){
        $result = curl_get($this->wxLoginUrl);

        $wxResult = json_decode($result,true);

        if(empty($wxResult)){
            throw new Exception('获取session_key及openid异常，微信内部错误');
        }else{
            $rst = array_key_exists('errcode',$wxResult);

            if($rst){
                $this-> processLoginError($wxResult);
            }else{
                return $this -> grantToken($wxResult);
            }
        }

    }

    private function grantToken($wxResult){
        //拿到openid
        //数据库查找，该openid是否已经存在
        //在，则不处理，不再新增加一条user记录
        //生成令牌，准备缓存数据，写入缓存
        //把令牌返回客户端去
        //key:令牌
        //value:wxResult,uid,scope
        $openid = $wxResult['openid'];
        $user = UserModel::getByopenId($openid);
        if($user){
            $uid = $user->id;
        }else{
            $uid = $this->newUser($openid);
        }

        $cachedValue = $this->prepareCachedValue($wxResult,$uid);
        $key  = $this->saveToCache($cachedValue);
        return $key;

        
    }

    private function newUser( $openid){
        $user = UserModel::create(
            [
                'openid' => $openid,
            ]
        );
        return $user;
    }

    private function prepareCachedValue($wxResult,$uid){
        $cachedValue = $wxResult;
        $cachedValue['uid'] = $uid;
        $cachedValue['scope'] = ScopeEnum::user;
        return $cachedValue;
    }

    private function saveToCache($cachedValue){
        $key = self::generateToken();
        $value = json_encode($cachedValue);

        $expire_in = config('setting.token_expire_in');
        $request = Cache::set($key,$value,$expire_in);
        if(!$request){
            throw new TokenException(
                [
                    'msg' => '服务器缓存异常',
                    '$errorCode' =>10005,
                ]
            );
        }
        return $key;
    }


    private function processLoginError($wxResult){
        throw new WeChatException(
            [
                'msg' => $wxResult['errmsg'],
                'errorCode' => $wxResult['errcode']
           ]
            );
    }


}